package com.mdoya.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mdoya.domain.Category;
import com.mdoya.dto.DishDto;
import com.mdoya.domain.Dish;
import com.mdoya.domain.DishFlavor;
import com.mdoya.exception.BusinessExceptiion;
import com.mdoya.mapper.DishMapper;
import com.mdoya.query.BaseQuery;
import com.mdoya.service.CategoryService;
import com.mdoya.service.DishFlavorService;
import com.mdoya.service.DishService;
import com.mdoya.vo.DishVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author mdoya
 * @version 1.0
 * @description:
 */
@Scope("singleton")
@Service
@Transactional(propagation = Propagation.REQUIRED)
public class DishServiceImpl implements DishService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private DishMapper dishMapper;
    @Autowired
    private DishFlavorService dishFlavorService;
    @Lazy
    @Autowired
    private CategoryService categoryService;

    @Override
    public Integer selectCategoryById(Long categoryId) {
        LambdaQueryWrapper<Dish> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Dish::getCategoryId, categoryId);
        return dishMapper.selectCount(wrapper);
    }

    /**
     * 添加菜品
     *
     * @param dishDto
     * @return
     */
    @Override
    public Integer add(DishDto dishDto) {
        // 删除redis中缓存
        redisTemplate.delete("dish_" + dishDto.getCategoryId() + "_1");
        // 1. 添加菜品
        int row = dishMapper.insert(dishDto);
        // 2. 添加口味
        List<DishFlavor> flavors = dishDto.getFlavors();

        if (flavors != null) {

            List<Integer> collect = flavors.stream().map((e) -> {
                int dishFlavorRows = 0;
                e.setDishId(dishDto.getId());
                dishFlavorRows += dishFlavorService.add(e);
                return dishFlavorRows;
            }).collect(Collectors.toList());
            return row > 0 && collect.size() == flavors.size() ? 1 : 0;
        }
        return row;
    }

    /**
     * 分页查询
     *
     * @param baseQuery
     * @return
     */
    @Override
    public IPage<DishVo> selectPage(BaseQuery baseQuery) {
        // 封装dish数据
        IPage<Dish> dishIPage = new Page<>(baseQuery.getPage(), baseQuery.getPageSize());
        LambdaQueryWrapper<Dish> dishLambdaQueryWrapper = new LambdaQueryWrapper<>();
        dishLambdaQueryWrapper.like(baseQuery.getName() != null, Dish::getName, baseQuery.getName());
        dishMapper.selectPage(dishIPage, dishLambdaQueryWrapper);

        // 封装DishVo数据
        IPage<DishVo> dishVoIPage = new Page<>();
        dishVoIPage.setTotal(dishIPage.getTotal());

        List<DishVo> dishVoList = dishIPage.getRecords().stream().map((item) -> {
            DishVo dishVo = new DishVo();
            BeanUtils.copyProperties(item, dishVo);
            // 拿到分类名称
            Category category = categoryService.selectTypeCategory(item.getCategoryId());
            if (category != null) {
                dishVo.setCategoryName(category.getName());
            }
            // 拿到口味表的数据
            List<DishFlavor> dishFlavorList = dishFlavorService.findByDishIdDishFlavo(item.getId());
            dishVo.setFlavors(dishFlavorList);
            return dishVo;
        }).collect(Collectors.toList());
        // 封装赋值给分页返回给前端
        dishVoIPage.setRecords(dishVoList);
        return dishVoIPage;
    }

    /**
     * 更新菜品
     *
     * @param dishDto
     * @return
     */
    @Override
    public Integer updateById(DishDto dishDto) {
        // 拿到原来分类的id
        Dish dish = dishMapper.selectById(dishDto.getId());

        // 修改菜品
        int rows = dishMapper.updateById(dishDto);

        // 删除所有口味
        dishFlavorService.deleteDishFlavor(dishDto.getId());
        Integer row = 0;
                // 再新增现有口味
        List<DishFlavor> flavors = dishDto.getFlavors();
        if (rows > 0 && flavors != null) {
            List<Integer> collect = flavors.stream().map((item) -> {
                item.setDishId(dishDto.getId());
                Integer row2 = dishFlavorService.add(item);
                return row2;
            }).collect(Collectors.toList());

            row = rows > 0 && collect.size() == flavors.size() ? 1 : 0;
        }
        // 原来分类和新分类校验是否一致
        long oldCategoryId = dish.getCategoryId();
        long newCategoryId = dishDto.getCategoryId();
        // 相同分类 删除一个redis中缓存
        if (oldCategoryId == newCategoryId ){
            redisTemplate.delete("dish_" + oldCategoryId + "_1");
        }
        // 不同分类，删除两个在redis中的缓存
        redisTemplate.delete("dish_" + oldCategoryId + "_1");
        redisTemplate.delete("dish_" + newCategoryId + "_1");
        return rows;
    }

    /**
     * 批量删除     修改状态
     *
     * @param ids id
     * @return
     */
    @Override
    public Integer batchDeleteIds(List<Long> ids) {

        List<Dish> dishList = dishMapper.selectBatchIds(ids);
        List<Integer> idsRows = dishList.stream().map((item) -> {
            System.err.println("==="+ item.getId());
            if (item.getStatus() == 1) {
                throw new BusinessExceptiion(-1, "正在销售，禁止删除");
            }
            LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Dish::getId,item.getId());
            item.setIsDeleted(1);
            return dishMapper.update(item, queryWrapper);
        }).collect(Collectors.toList());

        // 删除redis缓
        ids.stream().forEach((dishId) -> {
            Dish dish = dishMapper.selectById(dishId);
            System.err.println(dish.getCategoryId());
            redisTemplate.delete("dish_" + dish.getCategoryId() + "_1");
        });

        return idsRows.size() == ids.size() ? 1 : 0;

        /*  List<Integer> idsRows = ids.stream().map((id) -> {
            Dish dish = dishMapper.selectById(id);

            dish.setIsDeleted(1);
            int rows = dishMapper.updateById(dish);
            return rows;
        }).collect(Collectors.toList());*/
    }

    /**
     * 批量处理菜品状态
     *
     * @param map
     * @return
     */
    @Override
    public Integer batchSaleIds(Map map) {
        // map集合 键值对 id
        String id = (String) map.get("id");
        String[] split = id.split(",");
        String status = (String) map.get("status");
        int rows = 0;
        for (String str : split) {
            Dish dish = dishMapper.selectById(str);
            dish.setStatus(Integer.valueOf(status));
            rows += dishMapper.updateById(dish);
        }
        return rows == split.length ? 1 : 0;
    }

    /**
     * 前端菜品展示  redis缓存
     *
     * @param categoryId
     * @return
     */
    @Override
    public List<DishDto> selectTypeCategoryList(Long categoryId) {
        // 1. redis缓存拿数据
        String redisList = (String) redisTemplate.opsForValue().get("dish_" + categoryId + "_1");
        if (redisList != null) {
            return JSON.parseObject(redisList, List.class);
        }
        // 2. 数据库拿数据
        LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Dish::getCategoryId, categoryId);
        List<Dish> dishList = dishMapper.selectList(queryWrapper);
        List<DishDto> dishDtoList = dishList.stream().map((item) -> {
            DishDto dishDto = new DishDto();
            BeanUtils.copyProperties(item, dishDto);
            List<DishFlavor> dishFlavorList = dishFlavorService.findByDishIdDishFlavo(item.getId());
            dishDto.setFlavors(dishFlavorList);
            return dishDto;
        }).collect(Collectors.toList());
        redisTemplate.opsForValue().set("dish_" + categoryId + "_1", JSON.toJSONString(dishDtoList));
        return dishDtoList;
    }
}
